package org.example.leetcode.codeExecutor.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.text.StrSubstitutor;
import org.example.leetcode.codeExecutor.service.CodeExecuteFlow;
import org.example.leetcode.codeExecutor.utils.MinIOUtils;
import org.example.leetcode.codeExecutor.utils.SSHTools;
import org.example.leetcode.common._enum.CodeStatusEnum;
import org.example.leetcode.common._enum.IsTestOrSubmit;
import org.example.leetcode.common._enum.LanguageEnum;
import org.example.leetcode.common.domain.CodeDO;
import org.example.leetcode.common.domain.CodeResult;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

@Service
@Slf4j
public class CExecutor extends CodeExecuteFlow {
    @Resource
    MinIOUtils minIOUtils;

//    public String compileFileAndExecute(CodeDO codeDO, MinIOUtils.FileDto codeFile, CodeResult codeResult) {
//        String imageName=codeDO.getTitle()+codeDO.getPhone()+codeDO.getLanguage().toLowerCase();
//        String testFile=null;
//        try {
//            //远程服务器下载代码文件到指定路径
//            SSHTools.downloadCodeFile(MinIOUtils.LEETCODE,codeDO.getPhone(),codeDO.getLanguage(),codeFile.getFileName());
//            //初步编译
//            try{
//                String compile = SSHTools.compile(LanguageEnum.C.getCompileCode(), codeFile.getFileName(),LanguageEnum.C.getCode());
//                if(!StringUtils.isEmpty(compile)){
//                    codeResult.setStatus(CodeStatusEnum.compile_error.getCode());
//                    codeResult.setMessage(compile);
//                    return null;
//            }
//            }catch (Exception e){
//                codeResult.setStatus(CodeStatusEnum.compile_error.getCode());
//                codeResult.setMessage(CodeStatusEnum.compile_error.getName());
//                return null;
//            }
//            //构建镜像
//            SSHTools.SSHResult buildResult = SSHTools.buildDockerImage(imageName, codeFile.getFileName(), LanguageEnum.C);
//            //获取测试用例文件,需要管理员自行放置在minio中
//            testFile = IsTestOrSubmit.SUBMIT.getCode().equals(codeDO.getIsTestOrSubmit())
//                    ?SSHTools.getTestFile(codeDO.getTitle())
//                    :getMyTestFile(codeDO);
//            //docker执行代码
//            String res=SSHTools.runDocker(imageName, testFile,codeResult);
//            return res;
//        }catch (Exception e){
//            log.error(e.getMessage());
//            codeResult.setStatus(CodeStatusEnum.error.getCode());
//            codeResult.setMessage(e.getMessage());
//        }
//        finally {
//            CountDownLatch countDownLatch=new CountDownLatch(1);
//            String finalTestFile = testFile;
//            new Thread(()->{
//                String imageN=imageName;
//                MinIOUtils.FileDto codeF=new MinIOUtils.FileDto();
//                BeanUtils.copyProperties(codeFile,codeF);
//                countDownLatch.countDown();
//                //删除无用容器
//                SSHTools.deleteContainerByImageName(imageN);
//                SSHTools.deleteUnusedContainer();
//                SSHTools.deleteNoneImages();
//                SSHTools.deleteImages(imageN);
//                SSHTools.deleteFile(SSHTools.C_TARGET_URL+"/"+codeF.getFileName());
//                SSHTools.deleteFile(finalTestFile);
//                //删除minio的文件
//                try {
//                    MinIOUtils.removeFile(MinIOUtils.LEETCODE,codeF.getObjectName());
//                } catch (Exception e) {
//                    throw new RuntimeException(e);
//                }
//            }).start();
//            try {
//                countDownLatch.await();
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        return null;
//    }

//    public String getMyTestFile(CodeDO codeDO) {
//        File file=null;
//        try {
//            file=File.createTempFile("temp",LanguageEnum.C.getSuffix());
//            BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
//            bufferedWriter.write(codeDO.getTestData());
//            bufferedWriter.close();
//            String objectName="/temp/"+codeDO.getTitle()+codeDO.getLanguage()+codeDO.getPhone()+System.currentTimeMillis()+".txt";
//            MinIOUtils.uploadFile(MinIOUtils.LEETCODE,objectName,file.getAbsolutePath());
//            SSHTools.downloadFile(MinIOUtils.getBasisUrl()+objectName.substring(1),SSHTools.BASE_URL+objectName.substring(1));
//            return SSHTools.TEMP_URL+"/"+objectName.substring(objectName.lastIndexOf("/")+1);
//        } catch (Exception e) {
//            log.error("获取自定义测试用例错误");
//            throw new RuntimeException(e);
//        }
//        finally {
//            if(file.exists()){
//                file.delete();
//            }
//        }
//
//    }

    @Override
    public LanguageEnum getLanguageEnum() {
        return LanguageEnum.C;
    }

    @Override
    protected String compile(String fileUrl) {
        Map<String,String> map=new HashMap<>();
        map.put("compileCode","gcc");
        map.put("fileUrl",fileUrl);
        map.put("targetFile",fileUrl.substring(0,fileUrl.lastIndexOf(".")));
        map.put("targetUrl",SSHTools.BASE_URL+getLanguageEnum().getCode());
        String s="cd ${targetUrl} && ${compileCode} ${fileUrl} -o ${targetFile}";
        StrSubstitutor strSubstitutor=new StrSubstitutor(map);
        String cmd = strSubstitutor.replace(s);
        try {
            SSHTools.SSHResult sshResult = SSHTools.getSSHTools().executeShell(cmd);
            return StringUtils.isEmpty(sshResult.getError())?null:sshResult.getError().substring(sshResult.getError().indexOf(":")+1);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected String getExecuteCmd(String execFile,String testFile) {
        Map<String,String> map=new HashMap<>();
        map.put("execFile",execFile);
        map.put("testFile",testFile);
        map.put("targetUrl",SSHTools.BASE_URL+getLanguageEnum().getCode());
        String s="cd ${targetUrl} && ./${execFile} < ${testFile}";
        StrSubstitutor strSubstitutor=new StrSubstitutor(map);
        String cmd = strSubstitutor.replace(s);
        return cmd;
    }

    @Override
    protected void getDeleteCmd(String execFile) {
        Map<String,String> map=new HashMap<>();
        map.put("execFile",execFile);
        map.put("targetUrl",SSHTools.BASE_URL+getLanguageEnum().getCode());
        String s="cd ${targetUrl} && rm -rf ${execFile}";
        StrSubstitutor strSubstitutor=new StrSubstitutor(map);
        String cmd = strSubstitutor.replace(s);
        try {
            SSHTools.getSSHTools().executeShell(cmd);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


//    public MinIOUtils.FileDto createCodeFile(CodeDO codeDO) {
//        File file = null;
//        try {
//            file = File.createTempFile("temp", LanguageEnum.C.getSuffix());
//            String codeText = codeDO.getCodeText();
//            OutputStream outputStream = new FileOutputStream(file);
//            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
//            bufferedWriter.write(codeText);
//            bufferedWriter.close();
//            outputStream.close();
//            //生成带minio地址
//            String objectName=generateFileName(codeDO);
//            MinIOUtils.uploadFile(MinIOUtils.LEETCODE,objectName,file.getAbsolutePath());
//            MinIOUtils.FileDto fileDto = new MinIOUtils.FileDto();
//            fileDto.setFileName(objectName.substring(objectName.lastIndexOf('/')+1));
//            fileDto.setObjectName(objectName);
//            return fileDto;
//        } catch (Exception e) {
//            log.error("代码写入文件失败");
//            throw new RuntimeException(e);
//        }finally {
//            if(file.exists()){
//                file.delete();
//            }
//        }
//    }

    @Override
    public String getSuffix() {
        return LanguageEnum.C.getSuffix();
    }
}
